home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / LOCK.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  18KB  |  704 lines

  1. /*    SCCS Id: @(#)lock.c    3.0    88/10/22
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include    "hack.h"
  6.  
  7. STATIC_PTR int NDECL(picklock);
  8. STATIC_PTR int NDECL(forcelock);
  9.  
  10. STATIC_VAR struct xlock_s {
  11.     int    door_or_box, picktyp;
  12.     struct rm  *door;
  13.     struct obj *box;
  14.     int chance, usedtime;
  15. } NEARDATA xlock;
  16.  
  17. #ifdef OVLB
  18.  
  19. static boolean FDECL(obstructed,(int,int));
  20.  
  21. STATIC_PTR
  22. int
  23. picklock() {    /* try to open/close a lock */
  24.  
  25.     if(!xlock.door_or_box) {    /* box */
  26.  
  27.         if((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy)) {
  28.         return((xlock.usedtime = 0));        /* you or it moved */
  29.         }
  30.     } else {        /* door */
  31.         if(xlock.door != &(levl[u.ux+u.dx][u.uy+u.dy])) {
  32.         return((xlock.usedtime = 0));        /* you moved */
  33.         }
  34.         switch (xlock.door->doormask) {
  35.         case D_NODOOR:
  36.             pline("This doorway has no door.");
  37.             return((xlock.usedtime = 0));
  38.         case D_ISOPEN:
  39.             pline("Picking the lock of an open door is pointless.");
  40.             return((xlock.usedtime = 0));
  41.         case D_BROKEN:
  42.             pline("This door is broken.");
  43.             return((xlock.usedtime = 0));
  44.         }
  45.     }
  46.  
  47.     if(xlock.usedtime++ >= 50
  48. #ifdef POLYSELF
  49.        || nohands(uasmon)
  50. #endif
  51.        ) {
  52.         You("give up your attempt to %s the lock.",
  53.           (xlock.door_or_box ? !(xlock.door->doormask & D_LOCKED) :
  54.            !xlock.box->olocked) ? "lock" :
  55.           ((xlock.picktyp == LOCK_PICK) ? "pick" : "open" ));
  56.  
  57.         return((xlock.usedtime = 0));
  58.     }
  59.  
  60.     if(rn2(100) > xlock.chance) return(1);        /* still busy */
  61.  
  62.     if(xlock.door_or_box) {
  63.         You("succeed in %sing the lock.",
  64.           !(xlock.door->doormask & D_LOCKED) ? "lock" :
  65.           ((xlock.picktyp == LOCK_PICK) ? "pick" : "open" ));
  66.         if(xlock.door->doormask & D_TRAPPED) {
  67.             b_trapped("door");
  68.             xlock.door->doormask = D_NODOOR;
  69.             mnewsym(u.ux+u.dx, u.uy+u.dy);
  70.             prl(u.ux+u.dx, u.uy+u.dy);
  71.         } else if(xlock.door->doormask == D_LOCKED)
  72.         xlock.door->doormask = D_CLOSED;
  73.         else xlock.door->doormask = D_LOCKED;
  74.     } else {
  75.         You("succeed in %sing the lock.",
  76.           (!xlock.box->olocked) ? "lock" :
  77.           (xlock.picktyp == LOCK_PICK) ? "pick" : "open" );
  78.         xlock.box->olocked = !xlock.box->olocked;
  79.         if(xlock.box->otrapped)    
  80.         (void) chest_trap(xlock.box, FINGER);
  81.     }
  82.     return((xlock.usedtime = 0));
  83. }
  84.  
  85. STATIC_PTR
  86. int
  87. forcelock() {    /* try to force a locked chest */
  88.  
  89.     register struct obj *otmp, *otmp2;
  90.     register struct obj *probj = fcobj;  /* initialize to make lint happy */
  91.  
  92.     if((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy))
  93.         return((xlock.usedtime = 0));        /* you or it moved */
  94.  
  95.     if(xlock.usedtime++ >= 50 || !uwep
  96. #ifdef POLYSELF
  97.        || nohands(uasmon)
  98. #endif
  99.        ) {
  100.         You("give up your attempt to force the lock.");
  101.  
  102.         return((xlock.usedtime = 0));
  103.     }
  104.  
  105.     if(xlock.picktyp) {    /* blade */
  106.  
  107.         if(rn2(1000-uwep->spe) > 992 && !uwep->cursed) {
  108.         /* for a +0 weapon, probability that it survives an unsuccessful
  109.          * attempt to force the lock is (.992)^50 = .67
  110.          */
  111.         pline("%sour %s broke!",
  112.               (uwep->quan > 1) ? "One of y" : "Y", xname(uwep));
  113.         useup(uwep);
  114.         You("give up your attempt to force the lock.");
  115.         return((xlock.usedtime = 0));
  116.         }
  117.     } else            /* blunt */
  118.         wake_nearby();    /* due to hammering on the container */
  119.  
  120.     if(rn2(100) > xlock.chance) return(1);        /* still busy */
  121.  
  122.     You("succeed in forcing the lock.");
  123.     xlock.box->olocked = !xlock.box->olocked;
  124.     if(!xlock.picktyp && !rn2(3)) {
  125.  
  126.         pline("In fact, you've totally destroyed the %s.",
  127.           xname(xlock.box));
  128.         for(otmp = fcobj; otmp; otmp = otmp2) {
  129.  
  130.         otmp2 = otmp->nobj;
  131.         if(otmp->cobj == xlock.box) {
  132.  
  133.             /* unlink it from the "contained" list */
  134.             if(otmp == fcobj) fcobj = otmp2;
  135.             else          probj->nobj = otmp2;
  136.  
  137.             if(!rn2(3) || otmp->olet == POTION_SYM)
  138.             free((genericptr_t) otmp);
  139.             else { /* spill it onto the floor */
  140.             otmp->nobj = xlock.box->nobj;
  141.             xlock.box->nobj = otmp;
  142.             otmp->cobj = (struct obj *)0;
  143.             place_object(otmp, u.ux, u.uy);
  144.             stackobj(otmp);
  145.             }
  146.         } else probj = otmp;
  147.         }
  148.         delobj(xlock.box);
  149.     }
  150.     return((xlock.usedtime = 0));
  151. }
  152.  
  153. #endif /* OVLB */
  154. #ifdef OVL0
  155.  
  156. void
  157. reset_pick() { xlock.usedtime = 0; }
  158.  
  159. #endif /* OVL0 */
  160. #ifdef OVLB
  161.  
  162. int
  163. pick_lock(pick) /* pick a lock with a given object */
  164.     register struct    obj    *pick;
  165. {
  166.     register int x, y, picktyp, c, ch;
  167.     register struct rm    *door;
  168.     register struct obj    *otmp;
  169.  
  170. #ifdef __GNULINT__
  171.     ch = 0;        /* GCC myopia */
  172. #endif
  173.     picktyp = pick->otyp;
  174.     if(xlock.usedtime && picktyp == xlock.picktyp) {
  175.  
  176.         You("resume your attempt to %s the lock.",
  177.           (xlock.door_or_box ? !(xlock.door->doormask & D_LOCKED) :
  178.            !xlock.box->olocked) ? "lock" :
  179.           ((xlock.picktyp == LOCK_PICK) ? "pick" : "open" ));
  180.  
  181.         set_occupation(picklock,
  182.                (picktyp == LOCK_PICK) ? "picking the lock" :
  183.                             "opening the lock",  0);
  184.         return(1);
  185.     }
  186.  
  187. #ifdef POLYSELF
  188.     if(nohands(uasmon)) {
  189.         You("can't hold a %s - you have no hands!", xname(pick));
  190.         return(0);
  191.     }
  192. #endif
  193.     if((picktyp != LOCK_PICK && picktyp != CREDIT_CARD &&
  194.         picktyp != SKELETON_KEY && picktyp != KEY)) {
  195.         impossible("picking lock with object %d?", picktyp);
  196.         return(0);
  197.     }
  198.     if(!getdir(1)) return(0);
  199.  
  200.     x = u.ux + u.dx;
  201.     y = u.uy + u.dy;
  202.     if((x == u.ux) && (y == u.uy)) { /* pick the lock on a container */
  203.         c = 'n';            /* in case there are no boxes here */
  204.         for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
  205.         if(Is_box(otmp) &&
  206.                    /* credit cards are only good for unlocking */
  207.                    (picktyp != CREDIT_CARD || otmp->olocked)) {
  208.             pline("There is %s here, %s the lock? ",
  209.             doname(otmp), (!otmp->olocked) ? "close" :
  210.             ((picktyp == LOCK_PICK) ? "pick" : "open" ));
  211.  
  212.             c = ynq();
  213.             if(c == 'q') return(0);
  214.             if(c == 'n') continue;
  215.  
  216.             if(picktyp == KEY && otmp->spe != pick->spe) {
  217.                 pline("The %s won't fit the lock.",xname(pick));
  218.                 return(1);
  219.             }
  220.             switch(picktyp) {
  221.             case CREDIT_CARD:
  222.                 ch = ACURR(A_DEX)+(20*(pl_character[0] == 'R'));
  223.                 break;
  224.             case LOCK_PICK:
  225.                 ch = 4*ACURR(A_DEX)+(25*(pl_character[0] == 'R'));
  226.                 break;
  227.             case SKELETON_KEY:
  228.                 ch = 75 + ACURR(A_DEX);
  229.                 break;
  230.             case KEY:
  231.                 ch = 1000;
  232.                 break;
  233.             default:    ch = 0;
  234.             }
  235.             if(otmp->cursed) ch /= 2;
  236.  
  237.             xlock.door_or_box = 0;
  238.             xlock.picktyp = picktyp;
  239.             xlock.box = otmp;
  240.             break;
  241.         }
  242.         if(c != 'y')
  243.         return(0);        /* decided against all boxes */
  244.     } else {            /* pick the lock in a door */
  245.         struct monst *mtmp;
  246.  
  247.         door = &levl[x][y];
  248.         if ((mtmp = m_at(x,y)) && canseemon(mtmp) && !mtmp->mimic) {
  249.         if (picktyp == CREDIT_CARD &&
  250. #ifdef ORACLE
  251.             (mtmp->isshk || mtmp->data == &mons[PM_ORACLE]))
  252. #else
  253.             mtmp->isshk)
  254. #endif
  255.             verbalize("No checks, no credit, no problem.");
  256.         else
  257.             kludge("I don't think %s would appreciate that.", mon_nam(mtmp));
  258.         return(0);
  259.         }
  260.         if(!IS_DOOR(door->typ)) {
  261. #ifdef STRONGHOLD
  262.         if (is_drawbridge_wall(x,y) >= 0)
  263.             You("%s no lock on the drawbridge.",
  264.                 Blind ? "feel" : "see");
  265.         else
  266. #endif
  267.         You("%s no door there.",
  268.                 Blind ? "feel" : "see");
  269.         return(0);
  270.         }
  271.         switch (door->doormask) {
  272.         case D_NODOOR:
  273.             pline("This doorway has no door.");
  274.             return(0);
  275.         case D_ISOPEN:
  276.             pline("Picking the lock of an open door is pointless.");
  277.             return(0);
  278.         case D_BROKEN:
  279.             pline("This door is broken.");
  280.             return(0);
  281.         default:
  282.             /* credit cards are only good for unlocking */
  283.             if(picktyp == CREDIT_CARD && !(door->doormask & D_LOCKED)) {
  284.             You("can't lock a door with a credit card.");
  285.             return(0);
  286.             }
  287.  
  288.             pline("%sock it? ", (door->doormask & D_LOCKED) ? "Unl" : "L" );
  289.  
  290.             c = yn();
  291.             if(c == 'n') return(0);
  292.  
  293.             switch(picktyp) {
  294.             case CREDIT_CARD:
  295.                 ch = 2*ACURR(A_DEX)+(20*(pl_character[0] == 'R'));
  296.                 break;
  297.             case LOCK_PICK:
  298.                 ch = 3*ACURR(A_DEX)+(30*(pl_character[0] == 'R'));
  299.                 break;
  300.             case SKELETON_KEY:
  301.                 ch = 70 + ACURR(A_DEX);
  302.                 break;
  303.             case KEY:
  304.                 pline("The %s won't fit the door.", xname(pick));
  305.                 return(1);
  306.             default:    ch = 0;
  307.             }
  308.             xlock.door_or_box = 1;
  309.             xlock.door = door;
  310.         }
  311.     }
  312.     flags.move = 0;
  313.     xlock.chance = ch;
  314.     xlock.picktyp = picktyp;
  315.     xlock.usedtime = 0;
  316.     set_occupation(picklock,
  317.                (picktyp == LOCK_PICK) ? "picking the lock" :
  318.                         "opening the lock",  0);
  319.     return(1);
  320. }
  321.  
  322. int
  323. doforce() {        /* try to force a chest with your weapon */
  324.  
  325.     register struct obj *otmp;
  326.     register int c, picktyp;
  327.  
  328.     if(!uwep ||    /* proper type test */
  329.        (uwep->olet != WEAPON_SYM && uwep->olet != ROCK_SYM &&
  330.                         uwep->otyp != PICK_AXE) ||
  331.        (uwep->otyp < DAGGER) ||
  332.        (uwep->otyp > VOULGE && uwep->olet != ROCK_SYM &&
  333.                         uwep->otyp != PICK_AXE)
  334.       ) {
  335.         You("can't force anything without a %sweapon.",
  336.           (uwep) ? "proper " : "");
  337.         return(0);
  338.     }
  339.  
  340.     picktyp = (uwep->otyp >= DAGGER && uwep->otyp <= KATANA);
  341.     if(xlock.usedtime && xlock.box && picktyp == xlock.picktyp) {
  342.         You("resume your attempt to force the lock.");
  343.         set_occupation(forcelock, "forcing the lock", 0);
  344.         return(1);
  345.     }
  346.  
  347.     /* A lock is made only for the honest man, the thief will break it. */
  348.     xlock.box = (struct obj *)0;
  349.     for(otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere)
  350.         if(Is_box(otmp)) {
  351.         if(otmp->olocked)
  352.             pline("There is %s here, force the lock? ", doname(otmp));
  353.         else {
  354.             pline("There is a %s here, but it's already unlocked.",
  355.               xname(otmp));
  356.             continue;
  357.         }
  358.  
  359.         c = ynq();
  360.         if(c == 'q') return(0);
  361.         if(c == 'n') continue;
  362.  
  363.         if(picktyp)
  364.             You("force your %s into a crack and pry.", xname(uwep));
  365.         else
  366.             You("start bashing it with your %s.", xname(uwep));
  367.         xlock.box = otmp;
  368.         xlock.chance = objects[otmp->otyp].wldam * 2;
  369.         xlock.picktyp = picktyp;
  370.         xlock.usedtime = 0;
  371.         break;
  372.         }
  373.  
  374.     if(xlock.box)    set_occupation(forcelock, "forcing the lock", 0);
  375.     else        You("decide not to force the issue.");
  376.     return(1);
  377. }
  378.  
  379. int
  380. doopen() {        /* try to open a door */
  381.     register int x, y;
  382.     register struct rm *door;
  383.     struct monst *mtmp;
  384.  
  385.     if(!getdir(1)) return(0);
  386.  
  387.     x = u.ux + u.dx;
  388.     y = u.uy + u.dy;
  389.     if((x == u.ux) && (y == u.uy)) return(0);
  390.  
  391.     if((mtmp = m_at(x,y)) && mtmp->mimic &&
  392.                 mtmp->m_ap_type == M_AP_FURNITURE &&
  393.                 mtmp->mappearance == S_cdoor &&
  394.                 !Protection_from_shape_changers) {
  395.         stumble_onto_mimic(mtmp);
  396.         return(1);
  397.     }
  398.  
  399.     door = &levl[x][y];
  400.  
  401.     if(!IS_DOOR(door->typ)) {
  402. #ifdef STRONGHOLD
  403.         if (is_db_wall(x,y)) {
  404.             pline("There is no obvious way to open the drawbridge.");
  405.             return(0);
  406.         }
  407. #endif
  408.         You("%s no door there.",
  409.                 Blind ? "feel" : "see");
  410.         return(0);
  411.     }
  412.  
  413.     if(!(door->doormask & D_CLOSED)) {
  414.       switch(door->doormask) {
  415.          case D_BROKEN: pline("This door is broken."); break;
  416.          case D_NODOOR: pline("This doorway has no door."); break;
  417.          case D_ISOPEN: pline("This door is already open."); break;
  418.          default:        pline("This door is locked."); break;
  419.       }
  420.       return(0);
  421.     }
  422.  
  423. #ifdef POLYSELF
  424.     if(verysmall(uasmon)) {
  425.         pline("You're too small to pull the door open.");
  426.         return(0);
  427.     }
  428. #endif
  429.     /* door is known to be CLOSED */
  430.     if (rnl(20) < (ACURR(A_STR)+ACURR(A_DEX)+ACURR(A_CON))/3) {
  431.         pline("The door opens.");
  432.         if(door->doormask & D_TRAPPED) {
  433.         b_trapped("door");
  434.         door->doormask = D_NODOOR;
  435.         } else
  436.         door->doormask = D_ISOPEN;
  437.         mnewsym(x,y);
  438.         prl(x,y);
  439.     } else {
  440.         pline("The door resists!");
  441.     }
  442.  
  443.     return(1);
  444. }
  445.  
  446. static
  447. boolean
  448. obstructed(x,y)
  449. register int x, y;
  450. {
  451.     if(MON_AT(x, y)) {
  452.         if (m_at(x,y)->mimic) goto obj;      
  453.         pline("%s stands in the way!", Blind ?
  454.             "Some creature" : Monnam(m_at(x,y)));
  455.         return(TRUE);
  456.     }
  457.     if (OBJ_AT(x, y) || levl[x][y].gmask) {
  458. obj:
  459.         pline("Something's in the way.");
  460.         return(TRUE);
  461.     }
  462.     return(FALSE);
  463. }
  464.  
  465. int
  466. doclose() {        /* try to close a door */
  467.     register int x, y;
  468.     register struct rm *door;
  469.     struct monst *mtmp;
  470.  
  471.     if(!getdir(1)) return(0);
  472.  
  473.     x = u.ux + u.dx;
  474.     y = u.uy + u.dy;
  475.     if((x == u.ux) && (y == u.uy)) {
  476.         You("are in the way!");
  477.         return(1);
  478.     }
  479.  
  480.     if((mtmp = m_at(x,y)) && mtmp->mimic &&
  481.                 mtmp->m_ap_type == M_AP_FURNITURE && 
  482.                 mtmp->mappearance == S_cdoor &&
  483.                 !Protection_from_shape_changers) {
  484.         stumble_onto_mimic(mtmp);
  485.         return(1);
  486.     }
  487.  
  488.     door = &levl[x][y];
  489.  
  490.     if(!IS_DOOR(door->typ)) {
  491. #ifdef STRONGHOLD
  492.         if (door->typ == DRAWBRIDGE_DOWN)
  493.             pline("There is no obvious way to close the drawbridge.");
  494.         else
  495. #endif
  496.         You("%s no door there.",
  497.                 Blind ? "feel" : "see");
  498.         return(0);
  499.     }
  500.  
  501.     if(door->doormask == D_NODOOR) {
  502.         pline("This doorway has no door.");
  503.         return(0);
  504.     }
  505.  
  506.     if(obstructed(x, y)) return(0);
  507.  
  508.     if(door->doormask == D_BROKEN) {
  509.         pline("This door is broken.");
  510.         return(0);
  511.     }
  512.  
  513.     if(door->doormask & (D_CLOSED | D_LOCKED)) {
  514.         pline("This door is already closed.");
  515.         return(0);
  516.     }
  517.  
  518.     if(door->doormask == D_ISOPEN) {
  519. #ifdef POLYSELF
  520.         if(verysmall(uasmon)) {
  521.          pline("You're too small to push the door closed.");
  522.          return(0);
  523.          }
  524. #endif
  525.         if (rn2(25) < (ACURR(A_STR)+ACURR(A_DEX)+ACURR(A_CON))/3) {
  526.         pline("The door closes.");
  527.         door->doormask = D_CLOSED;
  528.         mnewsym(x,y);
  529.         prl(x,y);
  530.         }
  531.         else pline("The door resists!");
  532.     }
  533.  
  534.     return(1);
  535. }
  536.  
  537. int
  538. boxlock(obj, otmp)    /* box obj was hit with spell effect otmp */
  539.             /* returns 1 if something happened */
  540.     register struct obj *obj, *otmp;    /* obj *is* a box */
  541. {
  542.     register boolean res = 0;
  543.  
  544.     switch(otmp->otyp) {
  545.         case WAN_LOCKING:
  546. #ifdef SPELLS
  547.         case SPE_WIZARD_LOCK:
  548. #endif
  549.             if(!obj->olocked) {
  550.                 pline("Klunk!");
  551.                 obj->olocked = !(obj->olocked);
  552.                 res = 1;
  553.             } else    res = 0;
  554.             break;
  555.         case WAN_OPENING:
  556. #ifdef SPELLS
  557.         case SPE_KNOCK:
  558. #endif
  559.             if(obj->olocked) {
  560.                 pline("Klick!");
  561.                 obj->olocked = !(obj->olocked);
  562.                 res = 1;
  563.             } else    res = 0;
  564.             break;
  565.     }
  566.     return(res);
  567. }
  568.  
  569. int
  570. doorlock(otmp,x,y)    /* door was hit with spell effect otmp */
  571.     register struct obj *otmp;
  572.     int x, y;
  573. {
  574.     register struct rm *door = &levl[x][y];
  575.     boolean res = 1;
  576.  
  577.     if(door->typ == SDOOR) {
  578.         if(otmp->otyp == WAN_OPENING
  579. #ifdef SPELLS
  580.            || otmp->otyp == SPE_KNOCK
  581. #endif /* SPELLS /**/
  582.           ) {
  583.         door->typ = DOOR;
  584.         door->doormask = D_CLOSED | (door->doormask & D_TRAPPED);
  585.         if(cansee(x,y)) pline("A section of the wall opens up!");
  586.         mnewsym(x,y);
  587.         return(1);
  588.         } else
  589.         return(0);
  590.     }
  591.  
  592. #ifdef STRONGHOLD
  593.     /* make sure it isn't an open drawbridge */
  594.     if (is_maze_lev && find_drawbridge(&x,&y)) {
  595.         if(otmp->otyp == WAN_OPENING
  596. #ifdef SPELLS
  597.            || otmp->otyp == SPE_KNOCK
  598. #endif /* SPELLS /**/
  599.           )
  600.             (void) open_drawbridge(x,y);
  601.         else
  602.             (void) close_drawbridge(x,y);
  603.         return 1;
  604.     }
  605. #endif
  606.  
  607.     switch(otmp->otyp) {
  608.         case WAN_LOCKING:
  609. #ifdef SPELLS
  610.         case SPE_WIZARD_LOCK:
  611. #endif
  612.         if(obstructed(x,y)) return 0;
  613.         if (cansee(x,y))
  614.         switch (door->doormask & ~D_TRAPPED) {
  615.             case D_CLOSED:
  616.                 pline("The door locks!");
  617.                 break;
  618.             case D_ISOPEN:
  619.                 pline("The door swings shut, and locks!");
  620.                 break;
  621.             case D_BROKEN:
  622.                 pline("The broken door reassembles and locks!");
  623.                 break;
  624.             case D_NODOOR:
  625.     pline("A cloud of dust springs up and assembles itself into a door!");
  626.                 break;
  627.             default: res = 0;
  628.         }
  629.         door->doormask = D_LOCKED | (door->doormask & D_TRAPPED);
  630.         mnewsym(x,y);
  631.         if(cansee(x,y)) prl(x,y);
  632.         break;
  633.         case WAN_OPENING:
  634. #ifdef SPELLS
  635.         case SPE_KNOCK:
  636. #endif
  637.         if(door->doormask & D_LOCKED) {
  638.             door->doormask = D_CLOSED | (door->doormask & D_TRAPPED);
  639.             if(cansee(x,y)) pline("The door unlocks!");
  640.         } else res = 0;
  641.         break;
  642.         case WAN_STRIKING:
  643. #ifdef SPELLS
  644.         case SPE_FORCE_BOLT:
  645. #endif
  646.         if(door->doormask & (D_LOCKED | D_CLOSED)) {
  647.             if(door->doormask & D_TRAPPED) {
  648.             if (MON_AT(x, y))
  649.                 (void) mb_trapped(m_at(x,y));
  650.             else if (flags.verbose)
  651.                 if (cansee(x,y))
  652.                    pline("KABOOM!!    You see a door explode.");
  653.                 else if (flags.soundok)
  654.                    You("hear a distant explosion.");
  655.             door->doormask = D_NODOOR;
  656.             mnewsym(x,y);
  657.             if (cansee(x,y)) prl(x,y);
  658.             break;
  659.             }
  660.             door->doormask = D_BROKEN;
  661.             if (flags.verbose)
  662.             if (cansee(x,y))
  663.                 pline("The door crashes open!");
  664.             else if (flags.soundok)
  665.                 You("hear a crashing sound.");
  666.             mnewsym(x,y);
  667.             if (cansee(x,y)) prl(x,y);
  668.         } else res = 0;
  669.         break;
  670.         default:    impossible("magic (%d) attempted on door.", otmp->otyp);
  671.     }
  672.     return res;
  673. }
  674.  
  675. #ifdef STUPID_CPP    /* otherwise these functions are macros in obj.h */
  676. int
  677. Is_container(otmp) struct obj * otmp; {
  678.     return(otmp->otyp >= ICE_BOX && otmp->otyp <= BAG_OF_TRICKS);
  679. }
  680.  
  681. int
  682. Is_box(otmp) struct obj * otmp; {
  683.     return(otmp->otyp == LARGE_BOX || otmp->otyp == CHEST);
  684. }
  685.  
  686. int
  687. Is_mbag(otmp) struct obj * otmp; {
  688.     return(otmp->otyp == BAG_OF_HOLDING || otmp->otyp == BAG_OF_TRICKS);
  689. }
  690.  
  691. int
  692. is_sword(otmp) struct obj * otmp; {
  693.     return(otmp->otyp >= SHORT_SWORD && otmp->otyp <= KATANA);
  694. }
  695.  
  696. int
  697. bimanual(otmp) struct obj * otmp; {
  698.     return((otmp->olet == WEAPON_SYM || otmp->otyp == UNICORN_HORN)
  699.         && objects[otmp->otyp].oc_bimanual);
  700. }
  701. #endif /* STUPID_CPP */
  702.  
  703. #endif /* OVLB */
  704.